package com.cwt_taxi_xa.protocol.can;

import android.os.Handler;

import com.cwt_taxi_xa.constants.ConstantsEvaluate;
import com.cwt_taxi_xa.model.ExtraInfo;
import com.cwt_taxi_xa.protocol.can.meter.MeterGeneral;
import com.cwt_taxi_xa.protocol.can.meter.SoftWareMeter;
import com.cwt_taxi_xa.protocol.card.cmd.BaseCmd;
import com.cwt_taxi_xa.service.FloatService;
import com.cwt_taxi_xa.util.AppLog;
import com.cwt_taxi_xa.util.ByteArrayUtil;
import com.cwt_taxi_xa.util.Tools;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * CAN车辆信息
 * @author undi
 *
 */
public class VehicleInformation {

	private static  final String TAG = "VehicleInformation";

	//除去canId部分
	private final int dataIndex = 3;
	//档位
	public static final String CAN_GEAR_ID = "42030000";
	//READY指示灯
	public static final String CAN_READY_LIGHT_ID = "41030000";

	//倒车指示灯
	public static final String CAN_REVERSE_LIGHT_ID = "75040000";

	//近光,远光,左转,右转示灯
	public static final String CAN_FEATURES_LIGHT_ID = "33010000";

	//近光,远光,左转,右转示灯
	public static final String CAN_CAR_DOOR_LIGHT_ID = "2D010000";

	//剩余电池电量
	public static final String CAN_BATTERY_POWER_ID = "47040000";

	//续驶里程(电 动车)(预留发3FF)
	public static final String CAN_DRIVING_RANGE_ID = "D9030000";

	//车速
	public static final String CAN_VEHICLE_SPEED_ID = "21010000";

	//车速Throttle depth
	public static final String CAN_DEPTH_ID = "42030000";//油门深度有效位/油门深度有效位

	public SoftWareMeter softWareMeter = new MeterGeneral();

	private int gear = 0;
	private int readyLight = 0;
	private int reverseLight = 0;
	private int nearLight = 0;
	private int farLight = 0;
	private int leftLight = 0;
	private int rightLight = 0;
	private double batteryPower = 0;	//剩余电量
	private int drivingRange = 0;		//续航里程
	private int totalMileage = 0;
	private double powerConsumption = 0;
	private int accelerator = 0;
	private int brake = 0;
	private int rightFrontDoor = 0;	//02 00
	private int leftBackDoor = 0;	//04 00
	private int rightBackDoor = 0;	//08 00
	private int trunkDoor = 0;		//10 00
	private int brakePedalStatus = 0;	//制动踏板状态  00 01
	private double vehicleSpeed = 0;


	List<WeakReference<IViewVehicleInfo>> weakReferenceArray = new ArrayList<>();


	private Handler mHandler = new Handler();

	public void init(){

	}

	private void init(IViewVehicleInfo viewVehicleInfo){
		viewVehicleInfo.gearPosition(gear);
		viewVehicleInfo.readyLight(readyLight);
		viewVehicleInfo.reverseLight(readyLight);
		viewVehicleInfo.featuresLight(nearLight,farLight,leftLight,rightLight);
		viewVehicleInfo.doorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
		viewVehicleInfo.batteryPower(batteryPower);
		viewVehicleInfo.drivingRange(drivingRange);
		viewVehicleInfo.totalMileage(totalMileage);
		viewVehicleInfo.powerConsumption(powerConsumption);
		viewVehicleInfo.vehicleSpeed(vehicleSpeed);
		viewVehicleInfo.depth(accelerator, brake);
	}

	public void register(IViewVehicleInfo viewVehicleInfo){
		if(!contains(viewVehicleInfo)){
			weakReferenceArray.add(new WeakReference<>(viewVehicleInfo));
			init(viewVehicleInfo);
		}
	}

	public void unregister(IViewVehicleInfo viewVehicleInfo){
		synchronized(weakReferenceArray){
			for(int i = 0; i < weakReferenceArray.size(); i++){
				if(viewVehicleInfo == weakReferenceArray.get(i).get()){
					weakReferenceArray.remove(i);
					break;
				}
			}
		}
	}

	public boolean contains(IViewVehicleInfo viewVehicleInfo){
		boolean result = false;
		synchronized(weakReferenceArray){
			for(int i = 0; i < weakReferenceArray.size(); i++){
				if(viewVehicleInfo == weakReferenceArray.get(i).get()){
					result = true;
					break;
				}
			}
		}
		return result;
	}

	void dispatchGearPosition(int value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.gearPosition(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchReadyLight(int value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.readyLight(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchReverseLight(int value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.reverseLight(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchFeaturesLight(int nearLight,int farLight,int leftLight,int rightLightValue){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.featuresLight(nearLight,farLight,leftLight,rightLightValue);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchDoorState(int rightFrontDoor,int leftBackDoor,int rightBackDoor,int trunkDoor,int brakePedalStatus){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.doorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}


	void dispatchBatteryPower(double value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.batteryPower(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchDrivingRange(int value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.drivingRange(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}


	void dispatchTotalMileage(int value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.totalMileage(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
			softWareMeter.onTotalMileageChange(value);
		}
	}


	void dispatchPowerConsumption(double value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.powerConsumption(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	void dispatchVehicelSpeed(double value){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.vehicleSpeed(value);
				}else{
					weakReferenceArray.remove(i);
				}
			}
			softWareMeter.onVehicleSpeedChange(value);
		}
	}


	void dispatchDepth(int accelerator,int brake){
		synchronized(weakReferenceArray){
			for(int i =0 ;i< weakReferenceArray.size(); i++){
				IViewVehicleInfo ViewVehicleInfo = weakReferenceArray.get(i).get();
				if(ViewVehicleInfo != null){
					ViewVehicleInfo.depth(accelerator,brake);
				}else{
					weakReferenceArray.remove(i);
				}
			}
		}
	}

	public int getRightFrontDoor() {
		return rightFrontDoor;
	}

	public int getRightBackDoor() {
		return rightBackDoor;
	}

	public int getLeftBackDoor() {
		return leftBackDoor;
	}

	public int getTrunkDoor() {
		return trunkDoor;
	}

	public double getVehicleSpeed() {
		return vehicleSpeed;
	}


	public void setGear(final int gear) {
		if(this.gear != gear){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchGearPosition(gear);
				}
			});
		}
		this.gear = gear;
	}

	public void setReadyLight(final int readyLight) {
		if(this.readyLight != readyLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchReadyLight(readyLight);
				}
			});
		}
		this.readyLight = readyLight;
	}

	public void setReverseLight(final int reverseLight) {
		if(this.reverseLight != reverseLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchReverseLight(reverseLight);
				}
			});
		}
		this.reverseLight = reverseLight;
	}

	public void setNearLight(final int nearLight) {
		if(this.nearLight != nearLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchFeaturesLight(nearLight,farLight ,leftLight ,rightLight);
				}
			});
		}
		this.nearLight = nearLight;
	}

	public void setFarLight(final int farLight) {
		if(this.farLight != farLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchFeaturesLight(nearLight,farLight ,leftLight ,rightLight);
				}
			});
		}
		this.farLight = farLight;
	}

	public void setLeftLight(final int leftLight) {
		if(this.leftLight != leftLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchFeaturesLight(nearLight,farLight ,leftLight ,rightLight);
				}
			});
		}
		this.leftLight = leftLight;
	}

	public void setRightLight(final int rightLight) {
		if(this.rightLight != rightLight){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchFeaturesLight(nearLight,farLight ,leftLight ,rightLight);
				}
			});
		}
		this.rightLight = rightLight;
	}

	public void setBatteryPower(final double batteryPower) {
		if((int)this.batteryPower != (int)batteryPower){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchBatteryPower(batteryPower);
				}
			});
		}
		this.batteryPower = batteryPower;
	}

	public void setDrivingRange(final int drivingRange) {
		if(this.drivingRange != drivingRange){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDrivingRange(drivingRange);
				}
			});
		}
		this.drivingRange = drivingRange;
	}

	public void setTotalMileage(final int totalMileage) {
		if(this.totalMileage != totalMileage){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchTotalMileage(totalMileage);
				}
			});
		}
		this.totalMileage = totalMileage;
	}

	public void setPowerConsumption(final double powerConsumption) {
		if((int)this.powerConsumption != (int)powerConsumption){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchPowerConsumption(powerConsumption);
				}
			});
		}
		this.powerConsumption = powerConsumption;
	}

	public void setAccelerator(final int accelerator) {
		if(this.accelerator != accelerator){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDepth(accelerator,brake);
				}
			});
		}
		this.accelerator = accelerator;
	}

	public void setBrake(final int brake) {
		if(this.brake != brake){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDepth(accelerator,brake);
				}
			});
		}
		this.brake = brake;
	}

	public void setRightFrontDoor(final int rightFrontDoor) {
		if(this.rightFrontDoor != rightFrontDoor){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDoorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}
			});
		}
		this.rightFrontDoor = rightFrontDoor;
	}

	public void setLeftBackDoor(final int leftBackDoor) {
		if(this.leftBackDoor != leftBackDoor){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDoorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}
			});
		}
		this.leftBackDoor = leftBackDoor;
	}

	public void setRightBackDoor(final int rightBackDoor) {
		if(this.rightBackDoor != rightBackDoor){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDoorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}
			});
		}
		this.rightBackDoor = rightBackDoor;
	}

	public void setTrunkDoor(final int trunkDoor) {
		if(this.trunkDoor != trunkDoor){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDoorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}
			});
		}
		this.trunkDoor = trunkDoor;
	}

	public void setBrakePedalStatus(final int brakePedalStatus) {
		if(this.brakePedalStatus != brakePedalStatus){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchDoorState(rightFrontDoor,leftBackDoor,rightBackDoor,trunkDoor,brakePedalStatus);
				}
			});
		}
		this.brakePedalStatus = brakePedalStatus;
	}

	public void setVehicleSpeed(final double vehicleSpeed) {
		if((int)this.vehicleSpeed != (int)vehicleSpeed){

			mHandler.post(new Runnable() {
				@Override
				public void run() {
					dispatchVehicelSpeed(vehicleSpeed);
				}
			});
		}
		this.vehicleSpeed = vehicleSpeed;
	}

	public int getTotalMileage() {
		return totalMileage;
	}

	public int getGear() {
		return gear;
	}

	public int getReadyLight() {
		return readyLight;
	}

	public double getBatteryPower() {
		return batteryPower;
	}

	public void decode(String cmdId, byte[] buffer){
		//|| "DE010000".equals(cmdId)
		if(CAN_GEAR_ID.equals(cmdId) ){
			gear(buffer[dataIndex + 4]);
			depth(buffer[dataIndex + 3]);
		}else if(CAN_READY_LIGHT_ID.equals(cmdId) ){
			readyLight(buffer[dataIndex + 2]);
		}else if(CAN_REVERSE_LIGHT_ID.equals(cmdId)){
			reverseLight(buffer[dataIndex + 4]);
		}else if(CAN_FEATURES_LIGHT_ID.equals(cmdId)){
			featuresLight(buffer[dataIndex + 1]);
		}else if(CAN_CAR_DOOR_LIGHT_ID.equals(cmdId)){
			doorState(buffer[dataIndex + 1],buffer[dataIndex + 2]);
		}else if(CAN_BATTERY_POWER_ID.equals(cmdId)){
			batteryPower(BaseCmd.byteToSubstring(buffer, dataIndex + 5, 2));
		}else if(CAN_DRIVING_RANGE_ID.equals(cmdId)){
			drivingRange(buffer);
		}else if(CAN_VEHICLE_SPEED_ID.equals(cmdId)){
			vehicleSpeed(buffer);
		}else if(CAN_DEPTH_ID.equals(cmdId)){
			//depth(buffer[dataIndex + 3]);
		}
	}




	private void gear(byte data){
		//0x0:保留/0x2:R 档
		//00 00 03 42
		//00 00 00 02 00 00 00 00
		//		   00
		final int value = data&0x0F;
		AppLog.d(TAG,"gear value:" + value);
		setGear(value);
	}

	private void readyLight(byte data){
		//0x0:不显示/0x1:显示/0x2-0x3:保留
		//00 00 03 41
		//00 01 00 00 00 00 00 00
		//	 02
		final int value = data&0x03;
		AppLog.d(TAG,"readyLight value:" + value);
		setReadyLight(value);
	}

	private void reverseLight(byte data){
		//0x0:无效/0x1:倒车灯点亮/0x2:倒车灯熄灭/0x3:预留
		//00 00 04 75
		//00 00 00 01 00 00 00 00
		final int value = data&0x03;
		AppLog.d(TAG,"reverseLight value:" + value);
		setReverseLight(value);
	}

	private void featuresLight(byte data){
		//0x0:无效/0x1:倒车灯点亮/0x2:倒车灯熄灭/0x3:预留
		//00 00 01 33
		//3C 00 00 00 00 00 00 00
		final int nearLightValue = (data>>2)&0x01;//04
		AppLog.d(TAG,"featuresLight near Light nearLightValue:" + nearLightValue);
		final int farLightValue = (data>>3)&0x01;//08
		AppLog.d(TAG,"featuresLight far Light farLightValue:" + farLightValue);
		final int leftLightValue = (data>>4)&0x01;//10
		AppLog.d(TAG,"featuresLight left Light leftLightValue:" + leftLightValue);
		final int rightLightValue = (data>>5)&0x01;//20
		AppLog.d(TAG,"featuresLight right Light rightLightValue:" + rightLightValue);

		setNearLight(nearLightValue);
		setFarLight(farLightValue);
		setLeftLight(leftLightValue);
		setRightLight(rightLightValue);
	}

	private void doorState(byte data,byte data2){
		//00 00 01 2D
		//1E 01 00 00 00 00 00 00
		final int rightFrontDoor = (data>>1)&0x01;//02 00
		final int leftBackDoor = (data>>2)&0x01;//04 00
		final int rightBackDoor = (data>>3)&0x01;//08 00
		final int trunkDoor = (data>>4)&0x01;//10 00
		final int brakePedalStatus = data2&0x01;//制动踏板状态  00 01
		AppLog.d(TAG,"doorState rightFrontDoor:" + rightFrontDoor + " leftBackDoor:" + leftBackDoor + " rightBackDoor:" + rightBackDoor + " trunkDoor:" + trunkDoor + " brakePedalStatus:" + brakePedalStatus);
		setRightFrontDoor(rightFrontDoor);
		setLeftBackDoor(leftBackDoor);
		setRightBackDoor(rightBackDoor);
		setTrunkDoor(trunkDoor);
		setBrakePedalStatus(brakePedalStatus);
	}

	/**
	 * 8位
	 * @param byteToSubstring
	 */
	private void batteryPower(byte[] byteToSubstring) {
		// TODO Auto-generated method stub
		//00 00 04 47
		//00 00 00 00 E8 03 00 00
		//E8 取值范围[0-E][0-F]
		final int value = smallBytes2Int16(byteToSubstring);
		AppLog.d(TAG,"batteryPower value:" + value + " floatValue" + (value * 0.1));
		setBatteryPower(value * 0.1);
	}

	/*
	 * 注意参数见低地址对应低位字节
	 * 小端模式
	 */
	private void drivingRange(byte[] buffer) {
		// TODO Auto-generated method stub
		//00 00 03 D9
		byte keyId = buffer[dataIndex + 1];
		AppLog.d(TAG,"drivingRange keyId:" + keyId + " 0x57:" + 0x57 + " 0xAA:" + 0xAA + " 0x55:" + 0x55);
		if(keyId == (byte)0x57){
			//57 00 00 00 00 00 F0 1F
			//57 00 00 00 00 00 F8 1F
			//实际数值排序F81F--[FE03]--03FE
			//续航里程 0,2046  {0, 3FE}
			final byte[] drivingRangeBuffer = BaseCmd.byteToSubstring(buffer, dataIndex + 7, 2);
			//byte[] drivingRangeBuffer = new byte[]{(byte) 0xF0,0x1F};
			AppLog.d(TAG, "drivingRange 0 0x57  hex:" + Tools.parseByte2HexStr(drivingRangeBuffer));
			//数据拆分
			drivingRangeBuffer[0] = (byte) ((drivingRangeBuffer[0]>>3) & 0x1F);//5位获取高位5位数据 F0->1E
			drivingRangeBuffer[1] = (byte) (drivingRangeBuffer[1]&0x3F);	   //6位 获取低位6位数据 1F-1F
			AppLog.d(TAG, "drivingRange 1 0x57  hex:" + Tools.parseByte2HexStr(drivingRangeBuffer));
			//数据重组
			drivingRangeBuffer[0] = (byte) ((((drivingRangeBuffer[1]&0x07)<<5)&0xE0) | (drivingRangeBuffer[0]));//取高3位左移5位|低5位
			drivingRangeBuffer[1] = (byte) ((drivingRangeBuffer[1]>>3)&0x07);//左移3位获取双字节高位
			AppLog.d(TAG, "drivingRange 2 drivingRange:" + smallBytes2Int16(drivingRangeBuffer) + " hex:" + Tools.parseByte2HexStr(drivingRangeBuffer));

			setDrivingRange(smallBytes2Int16(drivingRangeBuffer));

		}else if(keyId == (byte)0xAA){
			//AA 3F 42 0F 00 00 00 00 //AA 3F 42 0[0-F]
			//实际数值排序 3F420F--F4230F
			//总里程20byte
			final byte[] totalMileageBuffer = BaseCmd.byteToSubstring(buffer, dataIndex + 2, 3);
			totalMileageBuffer[2] = (byte) (totalMileageBuffer[2]&0x0F);//4位
			AppLog.d(TAG, "drivingRange  0xAA powerConsumption:" + smallBytes2Int20(totalMileageBuffer) + " hex:" + Tools.parseByte2HexStr(totalMileageBuffer));
			setTotalMileage(smallBytes2Int20(totalMileageBuffer));
		}else if(keyId == (byte)0x55){
			//55 00 00 00 00 00 E0 7C
			//实际数值排序CE07-- 07CE
			//平均电耗12byte
			byte[] powerConsumptionBuffer = BaseCmd.byteToSubstring(buffer, dataIndex + 7, 2);
			AppLog.d(TAG, "drivingRange 0x55 hex:" + Tools.parseByte2HexStr(powerConsumptionBuffer));
			//powerConsumptionBuffer[0] = (byte)((powerConsumptionBuffer[0]>>4)|((powerConsumptionBuffer[1]&0x0F) >> 4)&0xF0);//4位
			powerConsumptionBuffer[0] = (byte)(((powerConsumptionBuffer[0]>>4)&0x0F)|(((powerConsumptionBuffer[1]&0x0F) <<4)&0xF0));//4位
			powerConsumptionBuffer[1] = (byte) ((powerConsumptionBuffer[1]>>4)&0x0F);
			final int value = smallBytes2Int16(powerConsumptionBuffer);
			AppLog.d(TAG, "drivingRange 0x55 powerConsumption:" + value + " floatValue:" + (value * 0.1 - 99.9) + " hex:" + Tools.parseByte2HexStr(powerConsumptionBuffer));
			setPowerConsumption(value * 0.1 - 99.9);
		}
	}


	private void vehicleSpeed(byte[] buffer) {
		// TODO Auto-generated method stub
		//00 00 01 21
		//FE 0F 00 00 00 00 00 00  //F[0-E]
		//车辆速度[0;281.4625] km/h
		byte[] vehicleSpeedBuffer = BaseCmd.byteToSubstring(buffer, dataIndex + 1, 2);
		vehicleSpeedBuffer[1] = (byte) (vehicleSpeedBuffer[1]&0x0F);
		final int value = smallBytes2Int16(vehicleSpeedBuffer);
		AppLog.d(TAG, "vehicleSpeed value:" + value + " value:" + (value * 0.06875));
		setVehicleSpeed(value * 0.06875);

	}

	private void depth(byte data) {
		//00 00 03 42
		//00 00 03 00 00 00 00 00
		// TODO Auto-generated method stub
		final int acceleratorValue = data&0x01;
		AppLog.d(TAG,"depth acceleratorValue:" + acceleratorValue);
		setAccelerator(acceleratorValue);
		final int brakeValue = (data>>1)&0x01;
		AppLog.d(TAG,"depth brakeValue:" + brakeValue);
		setBrake(brakeValue);

	}

	/**
	 * 小端模式(Can数据)
	 * @param bytes
	 * @return
	 */
	public int smallBytes2Int16(byte[] bytes) {
		//int value = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
		int value = ((bytes[1]<<8)&0xFF00) | (bytes[0] & 0xFF);
		return value;
	}

	public static byte[] int32ToBytes(int value) {
		byte[] src = new byte[4];
		src[0] = (byte) ((value >> 24) & 0xFF);
		src[1] = (byte) ((value >> 16) & 0xFF);
		src[2] = (byte) ((value >> 8) & 0xFF);
		src[3] = (byte) (value & 0xFF);
		return src;
	}
	/**
	 * 小端模式
	 * @param bytes
	 * @return
	 * https://www.cnblogs.com/javaCommunication/p/8867740.html
	 */
	public int smallBytes2Int20(byte[] bytes) {
		//int value = ((bytes[2] & 0xff) << 16) |((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
		int value = ((bytes[2]<<16)& 0x0F0000) | ((bytes[1]<<8)&0xFF00) | (bytes[0] & 0xFF);
		return value;
	}

	/**
	 * 添加Can附加信息
	 * @return
	 */
	public byte[] getCanExtraInfo(){
		byte[] buffer = null;
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			//封装数据
			List<ExtraInfo> extraInfos = new ArrayList<>();

			extraInfos.add(new ExtraInfo((byte) 0x01, int32ToBytes(softWareMeter.getTotalMileage()))); //重车行驶里程
			extraInfos.add(new ExtraInfo((byte) 0xF7, new byte[]{(byte)FloatService.peopleNumber})); //重车行驶里程
			extraInfos.add(new ExtraInfo((byte) 0xD4, new byte[]{(byte) getReadyLight()}));//运行准备就绪
			extraInfos.add(new ExtraInfo((byte) 0xD6, new byte[]{(byte) ((int) getBatteryPower())}));//电量
			extraInfos.add(new ExtraInfo((byte) 0xD8, new byte[]{(byte) ((int) getGear())}));//档位
			int value = (rightFrontDoor << 1) | (leftBackDoor << 2) | (rightBackDoor << 3) | (trunkDoor << 4);
			extraInfos.add(new ExtraInfo((byte) 0xDE, new byte[]{(byte) ((int) value)}));//车门
			if(ConstantsEvaluate.openUpload()){
				extraInfos.add(new ExtraInfo((byte) 0xA0, ConstantsEvaluate.getEvaluatebyte()));//
			}
			//解析数据
			for (int i = 0; i < extraInfos.size(); i++) {
				ExtraInfo extraInfo = extraInfos.get(i);
				byte[] bufferItem = ByteArrayUtil.concatAll(new byte[]{extraInfo.getExtraCmd(), (byte) extraInfo.getBuffer().length}, extraInfo.getBuffer());
				baos.write(bufferItem);
			}
			buffer = baos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (baos != null) {
				try {
					baos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return buffer;
	}

	/**
	 * int到byte[] 由高位到低位
	 * @param i 需要转换为byte数组的整行值。
	 * @return byte数组
	 */
	public static byte[] intToByteArray(int i) {
		byte[] result = new byte[2];
		result[0] = (byte) ((i >> 8) & 0xFF);
		result[1] = (byte) (i & 0xFF);
		return result;
	}
}
